﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;

namespace QstkCore.DataAccess
{
    /// <summary>
    /// The New York stock exchange.
    /// </summary>
    public static class Nyse
    {
        private static readonly string DataFilePath;
        private static readonly IList<DateTime> GtsDates;

        static Nyse()
        {
            DataFilePath = Environment.GetEnvironmentVariable("QSDATA");
            if (DataFilePath == null)
            {
                Console.WriteLine("Have you set up the QSDATA environment variable?");
                throw new Exception("Have you set up the QSDATA environment variable?");
            }

            DataFilePath = Path.Combine(DataFilePath,"NYSE_dates.txt");

            GtsDates = GetData();
        }

        private static IList<DateTime> GetData()
        {
            IList<DateTime> dates = new List<DateTime>();
            var cultureInfo = new CultureInfo("en-US");

            using (var fs = File.Open(DataFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (var bs = new BufferedStream(fs, 262144))
            using (var sr = new StreamReader(bs))
            {
                while (true)
                {
                    string line = sr.ReadLine();
                    if (line == null) break;
                    try
                    {
                        dates.Add(DateTime.Parse(line, cultureInfo));
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }

            return dates;
        }

        /// <summary>
        /// Create a list of timestamps between startday and endday (inclusive)
        /// that correspond to the days there was trading at the NYSE. This function
        /// depends on a separately created a file that lists all days since July 4,
        /// 1962 that the NYSE has been open, going forward to 2020 (based
        /// on the holidays that NYSE recognizes).
        ///
        /// @param startday: First timestamp to consider (inclusive)
        /// @param endday: Last day to consider (inclusive)
        /// @return list: of timestamps between startday and endday on which NYSE traded
        /// @rtype datetime
        /// </summary>
        public static IEnumerable<DateTime> GetTradingDates(DateTime startDay, DateTime endDay, 
            TimeSpan timeOfDay = default(TimeSpan))
        {
            var startTime = startDay - timeOfDay;
            var endTime = endDay - timeOfDay;

            return from t in GtsDates where t >= startTime && t <= endTime select t + timeOfDay;
        }
    }
}
